package pl.edu.pw.elka.tinyrepo.trash;

import java.util.HashMap;
import java.util.Map;

import pl.edu.pw.elka.tinyrepo.common.Request;


/**
 * Fabryka skalowalna requestow na podstawie
 * przychodzacego naglowka.
 * 
 * @author Piotr Jarosik
 */
public class RequestFactory {
   /** Instancja fabryki do realizacji singleton'a. */
   private static RequestFactory instance = null;
   /** Zarejestrowane requesty. */
   private Map<String, Class<? extends Request>> reqMap  = 
      new HashMap<String, Class<? extends Request>>();
   
   /**
    * Zwraca jedyna instancje fabryki (singleton).
    * 
    * @return instancja fabryki.
    */
   static synchronized RequestFactory getInstance() {
      if(instance == null)
         instance = new RequestFactory();
      return instance;
   }
   
   /**
    * Rejestruje nowy rodzaj requesta do fabryki.
    * 
    * @param h - naglowek requesta.
    * @param rqClass - klasa requesta.
    */
   public void registerRequest(String h, Class<? extends Request> rqClass) {
      reqMap.put(h, rqClass);
   }
   
   /**
    * Tworzy nowy request na podstawie podanego
    * 
    * @param h - kod literowy zadania, bez bialych znakow.
    * @return zadany request.
    * @throws UnsupportedOperationException gdy request nie obslugiwany
    */
   public Request getRequest(String h) throws UnsupportedOperationException {
      Request r = null;
      Class<? extends Request> rClass = reqMap.get(h);
      if(rClass == null) // gdy podana operacja nie jest obslugiwana
         throw new UnsupportedOperationException("Unsupported request: "+h);
      try {
         r = rClass.newInstance();
      } catch (InstantiationException e) { // jak rzuci wyjatek to ktorys request nie ma konstruktora bezparametrowego
         e.printStackTrace();
         System.out.println("Cos nie tak z implementacja...");
      } catch (IllegalAccessException e) {
         e.printStackTrace();
         System.out.println("Cos nie tak z implementacja...");
      } 
      return r;
   }
   
   /**
    * Konstruktor rejestrujacy istniejace typy w fabryce. 
    */
   private RequestFactory() {
      registerRequest("GET", Request.class);
   }
}
